/*
 * Copyright (c) 2013-2013 XXXX XXXXXX, Inc.
 * XXXX Road, XXXX, XXXX State, XXXX Post code, XXXX Country.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of XXXX
 * XXXXXX, Inc. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with XXXX.
 * 
 * History
 * Date        Ver Author        Change Description
 * ----------- --- ------------- ----------------------------------------
 * 17 May 2013 002 Karl          Add elements
 * 24 May 2013 003 Karl          Add function to verify if a FE exists on current page.
 */
package test.com.sms.selenium.sms.resourcemanagement.util;

import static test.com.sms.selenium.sms.resourcemanagement.util.RmResourceManagementAdvancedSearchPageUtil.SEARCH_BUTTON_SEARCH;
import static test.com.sms.selenium.sms.resourcemanagement.util.RmResourceManagementAdvancedSearchPageUtil.SEARCH_INPUT_FIRST_NAME;
import static test.com.sms.selenium.sms.resourcemanagement.util.RmResourceManagementAdvancedSearchPageUtil.SEARCH_INPUT_LAST_NAME;
import static test.com.sms.selenium.sms.resourcemanagement.util.RmResourceManagementAdvancedSearchPageUtil.SEARCH_SELECT_REGION;
import static test.com.sms.selenium.sms.resourcemanagement.util.RmResourceManagementAdvancedSearchPageUtil.SEARCH_SELECT_RESOURCE_TYPE;
import static test.com.sms.selenium.sms.resourcemanagement.util.RmResourceManagementAdvancedSearchPageUtil.SEARCH_INPUT_COMPANY_NAME;

import java.util.HashMap;
import java.util.Map;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import test.com.sms.selenium.framework.SeleniumPageUtil;
import test.com.sms.selenium.util.SeleniumUtil;

public class RmResourceManagementPageUtil extends SeleniumPageUtil {
	public final static By RM_H1_TITLE = By.className("title");
	public final static By RM_LINK_SIGN_OUT = By.xpath("//a[text()='Sign Out']");
	public final static By RM_BUTTON_ADVANCED_SEARCH = By.xpath("//div[text()='Advanced Search']");
	public final static By RM_DIV_TOTAL_NO_OF_RESOURCES = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[1]/div[1]");
	public final static By RM_BUTTON_ADD_PERSON = By.xpath("//div[text()='Add Person']");
	public final static By RM_BUTTON_ADD_COMPANY = By.xpath("//div[text()='Add Company']");
	
	public final static By RM_BUTTON_SHOW_HIDE_MAP = By.xpath("//input[@value='Show/Hide Map'][@name='Hide Map']");
	public final static By RM_SELECT_RESOURCE_TYPE = By.id("resourceTypeCodeFilter");
	public final static By RM_SELECT_STATE = By.id("stateCodeFilter");
	public final static By RM_SELECT_WAREHOUSE = By.id("warehouseIdFilter");
	
	// different color icons
	public final static By RM_DIV_COLOR_ICON = By.xpath("//*[contains(@class,'feIndMini')]/..");
	public final static By RM_DIV_COLOR_ICONS = By.xpath("//*[contains(@class,'feIndMini feInd')]");
	
	public final static By RM_DIV_MAP = By.id("map-canvas");
	public final static By RM_DIV_INCIDENT_LIST = By.className("grid");
	
	/** elements of incident list*/
	public final static By RM_STRONG_NAME = By.xpath("//*[@id='fixed-header']/thead/tr/td[2]/strong");
	public final static By RM_STRONG_CITY = By.xpath("//*[@id='fixed-header']/thead/tr/td[3]/strong");
	public final static By RM_STRONG_STATE = By.xpath("//*[@id='fixed-header']/thead/tr/td[4]/strong");
	public final static By RM_STRONG_WAREHOUSE = By.xpath("//*[@id='fixed-header']/thead/tr/td[5]/strong");
	public final static By RM_STRONG_TKTS = By.xpath("//*[@id='fixed-header']/thead/tr/td[6]/strong");
	public final static By RM_STRONG_STATUS = By.xpath("//*[@id='fixed-header']/thead/tr/td[7]/strong");
	public final static By RM_STRONG_FES = By.xpath("//*[@id='fixed-header']/thead/tr/td[8]/strong");
	public final static By RM_STRONG_PHONE = By.xpath("//*[@id='fixed-header']/thead/tr/td[9]/strong");
	public final static By RM_STRONG_EMAIL = By.xpath("//*[@id='fixed-header']/thead/tr/td[10]/strong");
	public final static By RM_STRONG_RATES = By.xpath("//*[@id='fixed-header']/thead/tr/td[11]/strong");
	public final static By RM_STRONG_SKILLS = By.xpath("//*[@id='fixed-header']/thead/tr/td[12]/strong");
	public final static By RM_STRONG_CERT = By.xpath("//*[@id='fixed-header']/thead/tr/td[13]/strong");
	public final static By RM_STRONG_ORIGINATED = By.xpath("//*[@id='fixed-header']/thead/tr/td/strong[text()='Originated']");
	
	// Elements show after hide the map
	public final static By RM_STRONG_CLIENTS = By.xpath("//*[@id='fixed-header']/thead/tr/td/strong[text()='Clients']");
	public final static By RM_STRONG_JOB_TYPE = By.xpath("//*[@id='fixed-header']/thead/tr/td/strong[text()='Job Type']");
	
	public final static By RM_TBODY_RESULTS = By.xpath("//*[@id='table-data']/tbody");
	
	// icon of the resource type
	public final static By RM_DIV_FIELD_ENGINEER_FT   = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[1]");
	public final static By RM_DIV_FIELD_ENGINEER_PT = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[2]");
	public final static By RM_DIV_AFFILIATE = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[3]");
	public final static By RM_DIV_AFFILIATE_FE = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[4]");
	public final static By RM_DIV_PARTNER = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[5]");
	public final static By RM_DIV_PARTNER_FE = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[6]");
	public final static By RM_DIV_SUB_CONTRACTOR = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[7]");
	public final static By RM_DIV_SUBCONTRACTOR_FE = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[8]");
	public final static By RM_DIV_PLATFORM = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[9]");
	public final static By RM_DIV_PLATFORM_TECH = By.xpath("html/body/div[1]/div[2]/div[7]/div[2]/div[2]/div[10]");
	
	// first record of list
	public final static By RM_TR_FIRST_RECORD = By.xpath("//*[@id='table-data']/tbody/tr[1]");
	public final static By RM_TR_LAST_RECORD = By.xpath("//*[@id='table-data']/tbody/tr[last()]");
	public final static By RM_TR_RECORDS = By.xpath("//*[@id='table-data']/tbody/tr");
	
	// green field is the one of person's flag
	public final static By RM_TD_PERSONS = By.xpath("//*[@id='table-data']/tbody/tr/td[text()='JON  PETERS, SMS']/preceding-sibling::td[1]");

	// green field is the one of company's flag
	public final static By RM_TD_COMPANYS = By.xpath("//*[@id='table-data']/tbody/tr/td[text()='GAU NET']/preceding-sibling::td[1]");
	
	// the title of person and company
	public final static By RM_LABEL_TITLE_PERSON_OR_COMPANY = By.id("addresource");
	
	public final static void waitForResourceManagementPageLoad(){
		SeleniumUtil.waitOnElements(new By[]{
				RM_BUTTON_ADD_PERSON, RM_BUTTON_ADD_COMPANY, RM_BUTTON_SHOW_HIDE_MAP, 
				RM_SELECT_RESOURCE_TYPE, RM_SELECT_STATE, RM_SELECT_WAREHOUSE, RM_DIV_MAP, RM_DIV_INCIDENT_LIST
		});
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_BUTTON_ADD_PERSON)));
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_BUTTON_ADD_COMPANY)));
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_BUTTON_SHOW_HIDE_MAP)));
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_SELECT_RESOURCE_TYPE)));
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_SELECT_STATE)));
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_SELECT_WAREHOUSE)));
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_DIV_MAP)));
		SeleniumUtil.assertTrue(SeleniumUtil.isDisplayed(SeleniumUtil.getCachedElement(RM_DIV_INCIDENT_LIST)));
	}
	
	/**
	 * NOTE: don't use this function to find FE when there are too many FEs on 
	 * current page - it is too slow. Please filter and then call this method. 
	 * 
	 * History
	 * Date        Ver Author        Change Description
	 * ----------- --- ------------- ----------------------------------------
	 * 24 May 2013 003 Karl          Create, add function to verify if a FE exists on current page.
	 */
	public final static void assertFesExists(String[] firstNames, String[] lastNames, 
		String[] companyNames){
		
		if(!(firstNames.length == lastNames.length && lastNames.length == companyNames.length)){
			throw new IllegalArgumentException("First names, last names and company names array length must be a equal number.");
		}
		
		Map<Integer, Boolean> founds = new HashMap<Integer, Boolean>();
		int resultsSize = getFeCount();
		SeleniumUtil.assertTrue("There should be at least one record returned.", resultsSize > 0);
		
		for(int i=0; i < resultsSize; i++){
			String nameAndCompany = SeleniumUtil.findElement(SeleniumUtil.findElement(RM_TBODY_RESULTS), 
				By.xpath("./tr[" + (i+1) + "]/td[2]")).getText();
			for(int j=0; j<firstNames.length; j++){
				if(!founds.containsKey(j)){
					if(nameAndCompany.contains(firstNames[j]) && nameAndCompany.contains(lastNames[j]) && 
						nameAndCompany.contains(companyNames[j])){
						founds.put(j, true);
						if(founds.size() == firstNames.length){
							break;
						}
					}
				}
			}
			if(founds.size() == firstNames.length){
				break;
			}
		}
		
		for(int i=0; i < firstNames.length; i++){
			SeleniumUtil.assertTrue("Expected FE [" + firstNames[i] + " " + lastNames[i] + 
				", " + companyNames[i] + "] was not found in current page.", founds.get(i) != null);
		}
	}
	
	/**
	 * Assume current page is resource management main page. Get FE count in current page.
	 * */
	public static final int getFeCount(){
		return SeleniumUtil.findElements(
			SeleniumUtil.findElement(RM_TBODY_RESULTS), By.xpath("./tr")).size();
	}
	
	/**
	 * Assume current page is resource management main page. Do a advanced search 
	 * by first name and last name
	 */
	public static final void searchByPersonName(String firstName, String lastName){
		SeleniumUtil.click(SeleniumUtil.findElement(RM_BUTTON_ADVANCED_SEARCH));
		RmResourceManagementAdvancedSearchPageUtil.waitForAdvancedSearchPageLoad();
		
		// search
		RmResourceManagementAdvancedSearchPageUtil.clear();
		SeleniumUtil.sendKeys(SeleniumUtil.findElement(SEARCH_INPUT_FIRST_NAME), firstName);
		SeleniumUtil.sendKeys(SeleniumUtil.findElement(SEARCH_INPUT_LAST_NAME), lastName);
		SeleniumUtil.click(SeleniumUtil.findElement(SEARCH_BUTTON_SEARCH));
		SeleniumUtil.waitOnElements(new By[]{RM_TBODY_RESULTS});
		
		// enter the first found record
		SeleniumUtil.assertTrue("There should be at least one record returned by keyword [" + 
			firstName + " " + lastName + "].", getFeCount() > 0);
	}
	
	/**
	 * 31 May 2013
	 * 
	 * Enter the first Fe by first name and last name
	 * 
	 * */
	public static final void enterPersonPage(String firstName, String lastName, 
		String companyName){
		int resultsSize = getFeCount();
		SeleniumUtil.assertTrue("There should be at least one record at current page.", resultsSize > 0);
		
		WebElement foundLink = null;
		for(int i=0; i < resultsSize; i++){
			WebElement personLink = SeleniumUtil.findElement(SeleniumUtil.findElement(RM_TBODY_RESULTS), 
				By.xpath("./tr[" + (i+1) + "]/td[1]"));
			String nameAndCompany = SeleniumUtil.findElement(SeleniumUtil.findElement(RM_TBODY_RESULTS), 
				By.xpath("./tr[" + (i+1) + "]/td[2]")).getText();
			if(nameAndCompany.contains(firstName) && nameAndCompany.contains(lastName) && 
				nameAndCompany.contains(companyName)){
				foundLink = personLink;
				break;
			}
		}
		
		SeleniumUtil.assertTrue("Can't find any Fe with name ["+ firstName +" " + lastName + 
			"] and company [" + companyName + "].", foundLink != null);
		
		// enter person page
		SeleniumUtil.click(foundLink);
		RmResourceManagementPersonPageUtil.waitForPersonPageLoad();
	}
	
	/**
	 * Login into the resource manangent page, some records are hide. Because of the resource type
	 * and regions selects's default options which is selected are not 'All'. 
	 * Change the options of above 2 selects's default option is 'All'. 
	 */
	public static final void advancedSearchDefault(){
		SeleniumUtil.click(SeleniumUtil.findElement(RM_BUTTON_ADVANCED_SEARCH));
		RmResourceManagementAdvancedSearchPageUtil.waitForAdvancedSearchPageLoad();
		
		// search
		RmResourceManagementAdvancedSearchPageUtil.clear();
		SeleniumUtil.waitForFixedMilliseconds(100);
		SeleniumUtil.selectByVisibleText(new Select(SeleniumUtil.findElement(SEARCH_SELECT_REGION)), "All");
		SeleniumUtil.waitForFixedMilliseconds(100);
		SeleniumUtil.selectByVisibleText(new Select(SeleniumUtil.findElement(SEARCH_SELECT_RESOURCE_TYPE)), "All");
		
		SeleniumUtil.click(SeleniumUtil.findElement(SEARCH_BUTTON_SEARCH));
		SeleniumUtil.waitForFixedMilliseconds(3000);
		SeleniumUtil.waitOnElements(new By[]{RM_TBODY_RESULTS});
	}
	
	/**
	 * type a name and open it, whatever it's person or company
	 */
	public final static void openCompany(String name){
		final By COMPANY_TD_EDIT_COMPANY_FLAG = By.xpath("//*[@id='table-data']/tbody/tr/td[text()='" + 
				name + "']/preceding-sibling::td[1]");
		// change the status note and save it.
		SeleniumUtil.waitOnElements(new By[]{COMPANY_TD_EDIT_COMPANY_FLAG});
		SeleniumUtil.click(SeleniumUtil.findElement(COMPANY_TD_EDIT_COMPANY_FLAG));
		SeleniumUtil.waitForFixedMilliseconds(3000);
	}
	
	/**
	 * according to the company name search and open it
	 */
	public final static void searchByNameAndOpenCompany(String company){
		SeleniumUtil.click(SeleniumUtil.findElement(RM_BUTTON_ADVANCED_SEARCH));
		RmResourceManagementAdvancedSearchPageUtil.waitForAdvancedSearchPageLoad();
		
		// search
		RmResourceManagementAdvancedSearchPageUtil.clear();
		SeleniumUtil.sendKeys(SeleniumUtil.findElement(SEARCH_INPUT_COMPANY_NAME), company);
		SeleniumUtil.click(SeleniumUtil.findElement(SEARCH_BUTTON_SEARCH));
		SeleniumUtil.waitOnElements(new By[]{RM_TBODY_RESULTS});

		// open this record in tickets list
		openCompany(company);
	}
}
